/************************************************************
                   DEF: recalc
written by IL
edited by CAS
*************************************************************/
#include "fpp.h"
void contigsAlloc(int ctg);
void markercorrect(void);
extern int PRTMESS;
extern void updateproj(), refreshlist(), updatemarkerpos();

void recalc_clone_indices()
{
  int i;
  int max,index,j;
  Array acetmpdata=0;
  CLONE *clone,*tmp,clone2;
  BOOL found;
  struct markertop *markertop;
  struct marker *marker;
  struct markerclone *newmarker;
  struct remark *remptr;

  max= arrayMax(acedata); 

  acetmpdata = arrayReCreate (acetmpdata, 50, CLONE);
  contigsAlloc(max_contig);
  for(i=0;i<max;i++){ 
    clone2 =  arr(acedata, i, CLONE);
    if(strncmp("DELETE",clone2.clone,6)!=0){
      clone2.next = -1;
      if(!fppInsert(acetmpdata,clone2.clone,&index,cloneOrder))                 
	printf("ERROR check out\n");
      else
	array(acetmpdata,index, CLONE) = clone2;
    }
  }

  for(i=0;i<=max_contig;i++){
    contigs[i].count = contigs[i].seq = 0;
  }
  for(i=0;i<max;i++){ /* for each clone */
    clone2 = arr(acetmpdata,i,CLONE);
    if(clone2.ctg != 0){     
      j = clone2.ctg;
      if(j>max_contig){
	printf("ERROR ctg = %d, clone=%s,index = %d\n",j,clone2.clone,i);
      }
      contigsAlloc(j);
      if(contigs[j].count > 0){
	tmp = arrp(acetmpdata,contigs[j].last,CLONE);  
	tmp->next = i ;  
	contigs[j].count++;
	contigs[j].last = i;
	contigs[j].left = MiN(contigs[j].left, clone2.x);
	contigs[j].right = MaX(contigs[j].right, clone2.y);
	remptr = clone2.remark;
	found = FALSE;
	while(remptr != NULL && !found  ){
	  if(strstr(remptr->message,"seq")!= NULL){
	    contigs[j].seq++;
	    found = TRUE;
	  }
	  remptr = remptr->next;
	}
      }
      else{
	max_contig = MaX(max_contig, j);
	contigs[j].start = i;
	contigs[j].ctg = clone2.ctg;
	contigs[j].last = i ;
	contigs[j].count = 1;
	contigs[j].left = clone2.x;
	contigs[j].right = clone2.y;
	found = FALSE;
	remptr = clone2.remark;
	while(remptr != NULL && !found){
	  if(strstr(remptr->message,"sequenced")!= NULL){
	    contigs[j].seq++;
	    found = TRUE;;
	  }
	  remptr = remptr->next;
	}
      }
    }
  }

  for(i=0;i<max;i++){
    clone = arrp(acedata,i,CLONE);    
    markertop = clone->marker;
    while(markertop != NULL){
      if(fppFind(markerdata,markertop->marker,&index, markerOrder)){
	markertop->markerindex = index;
	marker = arrp(markerdata,markertop->markerindex,MARKER);
	marker->cloneindex = -1;
	newmarker=marker->nextclone;
	while(newmarker != NULL){
	  newmarker->cloneindex = -1;
	  newmarker = newmarker->nextclone;
	}
      }
      markertop = markertop->nextmarker;
    }
  }
  arrayDestroy(acedata);
  acedata = acetmpdata;
  max=arrayMax(acedata);

  markercorrect();

}

/**********************************************************
              DEF: recalccontigs
***********************************************************/
void recalccontigs()
{
  int i,j;
  CLONE *clone,*tmp;

  contigsAlloc(max_contig);
  for(i=0;i<=max_contig;i++) 
    contigs[i].count = contigs[i].seq = contigs[i].ctg = 0;
  

  for(i=0;i<arrayMax(acedata);i++){ /* set up the indexes for next in ctg etc */
      clone =  arrp(acedata, i, CLONE);
      clone->next = -1;
      if(clone->clone[0] == '!') continue;

      j = clone->ctg;
      contigsAlloc(j);
      if(contigs[j].count > 0){
         tmp = arrp(acedata,contigs[j].last,CLONE);
         tmp->next = i ;
         contigs[j].left = MiN(contigs[j].left, clone->x);
         contigs[j].right = MaX(contigs[j].right, clone->y);
      }
      else{
         max_contig = MaX(max_contig, j);
         contigs[j].start = i;
         contigs[j].ctg = clone->ctg;
         contigs[j].left = clone->x;
         contigs[j].right = clone->y;
      }
      contigs[j].count++;
      contigs[j].last = i;
      AddToCtgSeq(clone, j);
  }
  
  singleton = contigs[0].count;
  updateproj();
  refreshlist();
}

/***********************************************************
             DEF: recalccontigx
************************************************************/
void recalccontigx(int ctg)
/* does not calculate the clones that are in this contig. It only goes
through the ones it knows of and finds min,max and seq */
{
  int i;
  CLONE *clone;

  if(ctg > max_contig) return;
  contigs[ctg].left = INT_MAX;;
  contigs[ctg].right = INT_MIN;
  contigs[ctg].seq = 0;
  contigs[ctg].ctgstat = ND;

  for (i=contigs[ctg].start; i!= -1; i = clone->next)
  {
      clone = arrp(acedata,i,CLONE);
      if(contigs[ctg].left > clone->x) contigs[ctg].left = clone->x;
      if(contigs[ctg].right < clone->y) contigs[ctg].right = clone->y;
      AddToCtgSeq(clone, ctg);
  }
}

/*********************************************************
             checkmarkercontigbits
called by cloneedit 
**********************************************************/

void checkmarkercontigbits(int fromctg,int toctg)
{
  int dude,i;
  CLONE *clone;
  MARKER *marker;
  BOOL found=FALSE;
  struct markerctgpos *pos,*pos2;
  char str1[180];
  struct markertop *markertop;
  struct markerclone *markerclone;

  for(i=0;i<arrayMax(markerdata);i++){
    pos = arrp(markerdata,i,MARKER)->pos;
    while(pos!= NULL){
      if(pos->ctg == fromctg){
	found = FALSE;
	marker = arrp(markerdata,i,MARKER);
	if(arrp(acedata,marker->cloneindex,CLONE)->ctg == pos->ctg)
	  found = TRUE;
	markerclone = marker->nextclone;
	while(!found && markerclone != NULL){
	  if(arrp(acedata,markerclone->cloneindex,CLONE)->ctg == pos->ctg)
	    found = TRUE;
	  else
	    markerclone = markerclone->nextclone;
	}
	if(!found){
	  sprintf(str1,"Marker %s has now moved from ctg%d to ctg%d",arrp(markerdata,i,MARKER)->marker,
		  fromctg,toctg);
	  if (PRTMESS) displaymess(str1);
	  pos2 =arrp(markerdata,i,MARKER)->pos;
	  while(pos2!= NULL){
	    if(pos2->ctg == toctg)
	      found = TRUE;
	    pos2 = pos2->next;
	  }
	  if(found){/*need to deleted record for fromctg */
	    pos2 =arrp(markerdata,i,MARKER)->pos;
	    if(pos2->ctg == fromctg){
	      marker = arrp(markerdata,i,MARKER);
	      marker->pos = pos2->next;
	    }
	    else{
	      while(pos2->next->ctg != fromctg)
		pos2 =pos2->next;
	      pos2->next= pos2->next->next;
	    }

	    /* update new coordinates due to added clones */
	    pos2 = arrp(markerdata,i,MARKER)->pos;
	    while(pos2->ctg != toctg)
	      pos2 =pos2->next;
	    if(pos2->status == AUTO)
	      pos2->status = AUTOUPDATE;
	  }
	  else /* can overwrite record */
	    pos->ctg = toctg;
	}
      }
      pos = pos->next;
    }
  }
  /* now check for any new markers */
  dude = contigs[toctg].start;
  while(dude != -1){
    clone = arrp(acedata,dude,CLONE);
    if(clone->selected){
      markertop = clone->marker;
      while(markertop!=NULL){
	marker = arrp(markerdata,markertop->markerindex,MARKER);
	pos = marker->pos;
	found = FALSE;
	if(pos == NULL){	  
	  marker->pos = (struct markerctgpos *) 
	    messalloc((sizeof(struct markerctgpos)));
	  pos = marker->pos;
	}
	else{
	  while(pos !=NULL && !found){
	    if(pos->ctg == toctg)
	      found = TRUE;
	    pos = pos->next;
	  }	  
	  if(!found){
	    pos = marker->pos;
	    while(pos->next != NULL)
	      pos = pos->next;
	    pos->next = (struct markerctgpos *) 
	      messalloc((sizeof(struct markerctgpos)));
	    pos= pos->next;
	  }
	}
	if(!found){
	  pos->ctg = toctg;
	  pos->next = NULL;
	  pos->status = AUTOUPDATE;
	}
	markertop =markertop->nextmarker;
      }
      clone->selected = FALSE;
    }
    dude = clone->next;
  }
  updatemarkerpos(0);
}


